package com.whsxt.sys.common.config;

import java.util.HashMap;
import java.util.Map;


import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;
import com.whsxt.sys.common.UserRealm;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import lombok.Data;

@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(value = {SecurityManager.class})
@ConfigurationProperties(prefix = "shiro")
@Data
public class ShiroAutoConfiguration {
	
	private String [] anonUrl;
	private String logoutUrl;
	private String authcUrl;

	@Bean("credentialsMatcher")
	public HashedCredentialsMatcher hashedCredentialsMatcher() {
		HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
		hashedCredentialsMatcher.setHashAlgorithmName("md5");
		hashedCredentialsMatcher.setHashIterations(2);
		return hashedCredentialsMatcher;
	}
	
	@Bean("userRealm")
	public UserRealm userRealm(HashedCredentialsMatcher hashedCredentialsMatcher) {
		UserRealm userRealm = new UserRealm();
		userRealm.setCredentialsMatcher(hashedCredentialsMatcher);
		return userRealm;
	}
	
	@Bean("securityManager")
	public SecurityManager securityManager(UserRealm userRealm) {
		DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
		defaultWebSecurityManager.setRealm(userRealm);
		return defaultWebSecurityManager;
	}
	
	@Bean("shiroFilter")
	public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		shiroFilterFactoryBean.setLoginUrl("/index.html");
		Map<String, String> filterChainDefinitionMap = new HashMap<String, String>();
		if(anonUrl != null && anonUrl.length >0) {
			for (String string : anonUrl) {
				filterChainDefinitionMap.put(string, "anon");
			}
		}
		if(logoutUrl != null) {
			filterChainDefinitionMap.put(logoutUrl, "logout");
		}
		if(authcUrl != null) {
			filterChainDefinitionMap.put(authcUrl, "authc");
		}
		/*
		 * Map<String, Filter> filters = new HashMap<String, Filter>();
		 * filters.put("authc", new ShiroLoginFilter());
		 * shiroFilterFactoryBean.setFilters(filters);
		 */
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap );
		return shiroFilterFactoryBean;
	}
	
	@Bean
	public FilterRegistrationBean<DelegatingFilterProxy> delegatingFilterProxy(){
		FilterRegistrationBean<DelegatingFilterProxy> filterRegistrationBean = new FilterRegistrationBean<DelegatingFilterProxy>();
		DelegatingFilterProxy delegatingFilterProxy = new DelegatingFilterProxy();
		delegatingFilterProxy.setTargetFilterLifecycle(true);
		delegatingFilterProxy.setTargetBeanName("shiroFilter");
		filterRegistrationBean.setFilter(delegatingFilterProxy);
		return filterRegistrationBean;
	}
	
	/* 加入注解的使用，不加入这个注解不生效--开始 */
	/**
	 * 
	 * @param securityManager
	 * @return
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
		return authorizationAttributeSourceAdvisor;
	}

	@Bean
	public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
		DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
		advisorAutoProxyCreator.setProxyTargetClass(true);
		return advisorAutoProxyCreator;
	}
	/* 加入注解的使用，不加入这个注解不生效--结束 */

	/**
	 * 这里是为了能在html页面引用shiro标签，上面两个函数必须添加，不然会报错
	 * 
	 * @return
	 */
	@Bean("shiroDialect")
	public ShiroDialect shiroDialect() {
		return new ShiroDialect();
	}
}
